//
//  BaseRequest.swift
//  Asman
//
//  Created by 李旭峰 on 5/16/19.
//  Copyright © 2019 李旭峰. All rights reserved.
//

import Foundation
import UIKit

protocol RequestCallBack: class {
    func requestBaseUrl(_ request: BaseRequest) -> String?
    func requestDidSucess(_ request: BaseRequest)
    func requestDidFail(_ request: BaseRequest)
}

///数据整理
protocol RequestDataReformer: class {
    func reform(_ request: BaseRequest,_ data: [String:Any]? )
}
///数据校验器
protocol RequestDataValidator: class {
    func reponseIsValid(_ request: BaseRequest,_ data: [String:Any]? ) -> Bool
    func requestParamsIsValid(_ request: BaseRequest,_ data: [String:Any]? ) -> Bool
    func requestBodyIsValid(_ request: BaseRequest,_ data: Any? ) -> Bool
}
///请求参数源
protocol RequestParamSource: class {
    func requestParams(_ request: BaseRequest) -> [String:Any]?
}
///请求参数源
protocol RequestBodySource: class {
    func requestBody(_ request: BaseRequest) -> Any?
}
protocol RequestHeaderSource: class {
    func requestHeader(_ request: BaseRequest) -> [String:Any]?
}


enum RequestErrorType {
    case `default`
    case  success
    case  noContent
    case  params
    case  timeOut
    case  badnetwork
    case  server
    
    func errorMsg() -> String {
        switch self {
        case .badnetwork:
            return kText("当前无网络,请检查网络")
        case .timeOut:
            return kText("连接超时,请检查网络环境")
        case .params:
            return kText("数据异常,请稍候再试")
        case .default:
            return kText("当前无网络,请检查网络")
        case .server:
            return kText("连接超时,请检查网络环境")
        default:
            return kText("连接超时,请检查网络环境")
        }
    }
}


@objc enum PageRequestState:Int {
    case kInvalid
    case kReloading
    case kAppending
    case kSuccess
    case kError
    case kFinished
}

@objc enum RequestState:Int{
    case kInvalid
    case kStart
    case kReload
    case kLoading
    case kFinished
    case kError
    case kSuccess
}
class BaseRequest {
    
    weak var delegate: RequestCallBack?
    weak var dataReformer: RequestDataReformer?
    weak var dataValidator: RequestDataValidator?
    weak var paramSource: RequestParamSource?
    weak var bodySource: RequestBodySource?
    weak var headerSource: RequestHeaderSource?
    
    //MARK: 新增的参数，用户回调返回结果
    let szRequestId:String = UUID().uuidString.uppercased()
    
    var response : Response?
    var errorMsg: String = "请求超时，请检查网络是否正常"
    var requestId = 0
    init(_ target: RequestCallBack & RequestDataReformer & RequestParamSource & RequestBodySource & RequestHeaderSource) {
        self.dataValidator = self
        self.dataReformer = target
        self.paramSource = target
        self.bodySource = target
        self.headerSource = target
        self.delegate = target
    }
    init() {
        self.dataValidator = self
    }
    func loadData() {
        let customDomain = self.delegate?.requestBaseUrl(self)
        var baseUrl:String? = nil
//        if let tempCustomDomain = customDomain,tempCustomDomain.count >= 1 {
//            baseUrl = "http://\(tempCustomDomain).asman.com.cn"
//        }
        let params = self.paramSource?.requestParams(self)
        let body = self.bodySource?.requestBody(self)
        let customerHeader = self.headerSource?.requestHeader(self)
        self.loadData(baseUrl:baseUrl,customerHeader: customerHeader, query: params, body: body)
    }
    func loadData(baseUrl:String?,customerHeader:[String:Any]?,query:[String:Any]?,body:Any?){
        ///网络状态
        let isReachable = NetworkMonitor.default.isReachable
        if !isReachable {
            self.requestFailed(nil, .badnetwork)
        }
        self.requestId = RequestClient.default.request(self.server(),baseUrl:baseUrl, httpMethod: self.method(), methodName: self.path(), timeoutInterval: self.timeout(), mock: self.mock(), customerHeader: customerHeader, query: query, body: body, success: { (res) in
            dPrintServerResponse("******************************** response")
            dPrintServerResponse(self.path())
            dPrintServerResponse(res)
            dPrintServerResponse("******************************** response end")
            self.requestSucess(res)
        }) { (res) in
            dPrintServerResponse("******************************** response")
            dPrintServerResponse(self.path())
            dPrintServerResponse(res)
            dPrintServerResponse("******************************** response end")
            self.requestFailed(res, .server)
        }
        if self.dataValidator?.requestBodyIsValid(self, body) == true {
            
        }else {
            self.requestFailed(nil, .params)
        }
    }
    
    func requestFailed(_ response: Response?,_ errorType: RequestErrorType) {
        if self.openIndicator() {
            CXMBShow.colseIndicator()
        }
        self.errorMsg = errorType.errorMsg()
        self.delegate?.requestDidFail(self);
    }
    
    func requestSucess(_ response: Response?) {
        if self.openIndicator() {
            CXMBShow.colseIndicator()
        }
        if let data = response?.value as? [String:Any] {
            let code = String.SwitchToString(data["code"]) ?? "0"
            if code != "10000" {
                self.errorMsg = data["error"] as? String ?? ""
                self.response = response
                self.delegate?.requestDidFail(self)
                switch code {
                    /// 入参不正确
                    case "-10000":break
                    /// -10010(用户未登录)
                    ///-10040(登录超时)
                    /// -10060(账号被他人登录)
                    /// -10070(账号已停用)
                    case "-10010","-10040","-10060","-10070":
                        // 清理数据
                        // 跳转到登陆页
                    break
                    /// 访问未授权
                    case "-10020":break
                    /// 操作失败
                    case "-10030":break
                    /// 访问路径不存在
                    case "-10050":break
                    default:break
                }
                return
            }
        }
        if let flag = self.dataValidator?.reponseIsValid(self, response?.value as? [String : Any]), flag == true {
            self.delegate?.requestDidSucess(self)
            self.dataReformer?.reform(self, response?.value as? [String : Any])
        }else {
            requestFailed(response, .noContent)
        }
    }
    
    func cancelRequest() {
        if requestId != 0 {
            RequestClient.default.cancelRequest(taskIdentifier: requestId)
        }
    }
    
    fileprivate func mock() -> String {
        var mock = ""
        if ServerFactory.default.serverStatus == .cxMock {
            mock.append(mockId())
        }
        return mock
    }
    ///Requestable
    func path() -> String {
        return ""
    }
    
    func mockId() -> String {
        return ""
    }
    
    func method() -> HTTPMethodType {
        return .post
    }
    func timeout() -> TimeInterval {
        return kTimeOut
    }
    func server() -> Service {
        return Service.host
    }
    func useCache() -> Bool {
        return false
    }
    func openIndicator() -> Bool {
        return false
    }
}

extension BaseRequest : Requestable {}

extension BaseRequest : RequestDataValidator {
    func requestBodyIsValid(_ request: BaseRequest, _ data: Any?) -> Bool {
        return true
    }
    
    func reponseIsValid(_ request: BaseRequest,_ data: [String:Any]? ) -> Bool {
        return true
    }
    func requestParamsIsValid(_ request: BaseRequest,_ data: [String:Any]? ) -> Bool {
        return true
    }
    
}
